<!doctype html>
<meta charset="utf8">
<link rel="help" href="https://w3c.github.io/payment-request/#algorithms">
<title>
  Payment Request algorithms
</title>
<script src="/resources/testharness.js"></script>
<script src="/resources/testharnessreport.js"></script>
<script>
setup({
  explicit_done: true,
  explicit_timeout: true,
});
const methods = [
  {
    supportedMethods: "basic-card",
  },
  {
    supportedMethods: "https://apple.com/apple-pay",
    data: {
      version: 3,
      merchantIdentifier: "merchant.com.example",
      countryCode: "US",
      merchantCapabilities: ["supports3DS"],
      supportedNetworks: ["visa"],
    },
  }
];
const shippingOptions = {
  shippingOptions: [
    {
      id: "fail",
      label: "Option 1",
      amount: {
        currency: "USD",
        value: "5.00",
      },
      selected: true,
    },
    {
      id: "pass",
      label: "Option 2",
      amount: {
        currency: "USD",
        value: "5.00",
      },
    },
  ],
};

const detailsNoShippingOptions = {
  total: {
    label: "Total due",
    amount: {
      currency: "USD",
      value: "1.0",
    },
  },
};

const detailsWithShippingOptions = Object.assign(
  {
    total: {
      label: "Total due",
      amount: {
        currency: "USD",
        value: "1.0",
      },
    },
  },
  shippingOptions
);

const options = {
  requestShipping: true,
};

function testFireEvent(button, details, eventName, expectRequestProps) {
  button.disabled = true;
  promise_test(async t => {
    new PaymentRequest(methods, detailsNoShippingOptions, options);
    const request = new PaymentRequest(methods, details, options);
    const handlerPromise = new Promise(resolve => {
      request[`on${eventName}`] = event => {
        // "prevent immediate propagation" flag is set.
        // This listener below won't fire!
        event.updateWith(details);
        resolve(event);
      };
    });
    // This listener should never fire because the
    // the event handler caused "prevent immediate propagation" to be set.
    request.addEventListener(
      eventName,
      t.unreached_func("Second event listener should never fire")
    );
    const response = await request.show();
    const event = await handlerPromise;
    assert_true(
      event instanceof window.PaymentRequestUpdateEvent,
      "Expected instances of PaymentRequestUpdateEvent"
    );
    await response.complete("success");
  }, button.textContent.trim());
}

async function runAbortTest(button) {
  button.disabled = true;
  const { textContent: testName } = button;
  promise_test(async t => {
    const request = new PaymentRequest(methods, detailsNoShippingOptions);
    // Await the user to abort
    await promise_rejects_dom(t, "AbortError", request.show());
    // [[state]] is now closed
    await promise_rejects_dom(t, "InvalidStateError", request.show());
  }, testName.trim());
}
</script>
<h2>
  Tests for "algorithms" section
</h2>
<p>
  Click on each button in sequence from top to bottom without refreshing the page.
  Each button will bring up the Payment Request UI window.
</p>
<section>
  <h3 id="abort-algo">
    User aborts the payment request algorithm
  </h3>
  <link rel="help" href="https://w3c.github.io/payment-request/#user-aborts-the-payment-request-algorithm">
  <p>
    When presented with the payment sheet, abort the payment request (e.g., by hitting the esc key or pressing a UA provided button).
  </p>
  <ol>
    <li>
      <button onclick="runAbortTest(this);">
      If the user aborts, the UA must run the user aborts the payment request algorithm.
    </button>
    </li>
  </ol>
</section>

<section>
  <h3 id="shipping-address-changed-algo">Shipping address changed algorithm</h3>
  <link rel="help" href="https://www.w3.org/TR/payment-request/#shipping-address-changed-algorithm">
  <p>
    When prompted, please change or enter a new shipping address and then select Pay.
  </p>
  <ol>
    <li>
      <button onclick="testFireEvent(this, detailsWithShippingOptions, 'shippingaddresschange', {});">
      The shipping address changed algorithm runs when the user provides a new shipping address.
    </button>
    </li>
  </ol>
</section>

<section>
  <h3 id="shipping-option-changed-algo">Shipping option changed algorithm</h3>
  <link rel="help" href="https://w3c.github.io/payment-request/#shipping-option-changed-algorithm">
  <p>
    Finally, when prompted, please select "shipping option 2" and then select Pay.
  </p>
  <ol>
    <li>
      <button onclick="testFireEvent(this, detailsWithShippingOptions, 'shippingoptionchange', {}, 'pass'); done();">
      The shipping option changed algorithm runs when the user chooses a new shipping option.
    </button>
    </li>
  </ol>
</section>

<small>
  If you find a buggy test, please <a href="https://github.com/web-platform-tests/wpt/issues">file a bug</a>
  and tag one of the <a href="https://github.com/web-platform-tests/wpt/blob/master/payment-request/META.yml">suggested reviewers</a>.
</small>
